import React, { useState, useRef, useEffect } from 'react';
import {
    View,
    StyleSheet,
    TouchableOpacity,
    ActivityIndicator,
    Text,
    Platform,
    Dimensions,
} from 'react-native';
import { Video, AVPlaybackStatus, ResizeMode } from 'expo-av';
import { MaterialIcons } from '@expo/vector-icons';
import Slider from '@react-native-community/slider';

interface VideoPlayerProps {
    source: { uri: string } | number;
    autoPlay?: boolean;
    style?: any;
    onError?: (error: string) => void;
    onPlaybackStatusUpdate?: (status: AVPlaybackStatus) => void;
    poster?: string;
    showControls?: boolean;
    resizeMode?: ResizeMode;
}

const formatTime = (millis: number) => {
    const totalSeconds = millis / 1000;
    const seconds = Math.floor(totalSeconds % 60);
    const minutes = Math.floor(totalSeconds / 60);

    return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
};

const VideoPlayer: React.FC<VideoPlayerProps> = ({
    source,
    autoPlay = false,
    style,
    onError,
    onPlaybackStatusUpdate,
    poster,
    showControls = true,
    resizeMode = ResizeMode.CONTAIN,
}) => {
    const videoRef = useRef<Video>(null);
    const [status, setStatus] = useState<AVPlaybackStatus | null>(null);
    const [isPlaying, setIsPlaying] = useState<boolean>(autoPlay);
    const [isBuffering, setIsBuffering] = useState<boolean>(false);
    const [showOverlay, setShowOverlay] = useState<boolean>(true);
    const [position, setPosition] = useState<number>(0);
    const [duration, setDuration] = useState<number>(0);
    const [isSeeking, setIsSeeking] = useState<boolean>(false);
    const [error, setError] = useState<string | null>(null);
    const [isFullscreen, setIsFullscreen] = useState<boolean>(false);

    const overlayTimeoutRef = useRef<NodeJS.Timeout | null>(null);

    useEffect(() => {
        // Cleanup timeout on unmount
        return () => {
            if (overlayTimeoutRef.current) {
                clearTimeout(overlayTimeoutRef.current);
            }
        };
    }, []);

    const handlePlaybackStatusUpdate = (status: AVPlaybackStatus) => {
        setStatus(status);

        if (status.isLoaded) {
            setIsBuffering(status.isBuffering);

            if (!isSeeking) {
                setPosition(status.positionMillis);
            }

            if (status.durationMillis) {
                setDuration(status.durationMillis);
            }

            setIsPlaying(status.isPlaying);

            // Auto-hide overlay after a delay when playing
            if (status.isPlaying && showOverlay) {
                if (overlayTimeoutRef.current) {
                    clearTimeout(overlayTimeoutRef.current);
                }

                overlayTimeoutRef.current = setTimeout(() => {
                    setShowOverlay(false);
                }, 3000);
            }
        } else if (status.error) {
            console.error('Playback error:', status.error);
            setError(`Playback error: ${status.error}`);

            if (onError) {
                onError(status.error);
            }
        }

        if (onPlaybackStatusUpdate) {
            onPlaybackStatusUpdate(status);
        }
    };

    const togglePlayPause = async () => {
        if (videoRef.current) {
            if (isPlaying) {
                await videoRef.current.pauseAsync();
            } else {
                await videoRef.current.playAsync();
            }
        }
    };

    const handleValueChange = (value: number) => {
        setIsSeeking(true);
        setPosition(value);
    };

    const handleSlidingComplete = async (value: number) => {
        if (videoRef.current) {
            await videoRef.current.setPositionAsync(value);
            setIsSeeking(false);
        }
    };

    const toggleFullscreen = async () => {
        if (videoRef.current) {
            if (isFullscreen) {
                await videoRef.current.dismissFullscreenPlayer();
            } else {
                await videoRef.current.presentFullscreenPlayer();
            }
            setIsFullscreen(!isFullscreen);
        }
    };

    const replay = async () => {
        if (videoRef.current) {
            await videoRef.current.setPositionAsync(0);
            await videoRef.current.playAsync();
        }
    };

    const handleVideoPress = () => {
        setShowOverlay(!showOverlay);

        if (!showOverlay && overlayTimeoutRef.current) {
            clearTimeout(overlayTimeoutRef.current);
        }

        if (showOverlay && isPlaying) {
            overlayTimeoutRef.current = setTimeout(() => {
                setShowOverlay(false);
            }, 3000);
        }
    };

    const isFinished = status?.isLoaded && status.positionMillis > 0 &&
        status.positionMillis === status.durationMillis;

    return (
        <View style={[styles.container, style]}>
            <TouchableOpacity
                style={styles.videoContainer}
                activeOpacity={1}
                onPress={handleVideoPress}
            >
                <Video
                    ref={videoRef}
                    source={source}
                    style={styles.video}
                    resizeMode={resizeMode}
                    onPlaybackStatusUpdate={handlePlaybackStatusUpdate}
                    posterSource={poster ? { uri: poster } : undefined}
                    usePoster={!!poster}
                    useNativeControls={Platform.OS === 'web' && showControls}
                />

                {error ? (
                    <View style={styles.errorContainer}>
                        <MaterialIcons name="error-outline" size={48} color="white" />
                        <Text style={styles.errorText}>{error}</Text>
                    </View>
                ) : null}

                {(showOverlay && showControls && !error) || (Platform.OS !== 'web' && isBuffering) ? (
                    <View style={styles.overlay}>
                        {isBuffering ? (
                            <ActivityIndicator size="large" color="white" />
                        ) : (
                            <>
                                <View style={styles.controlsContainer}>
                                    <TouchableOpacity
                                        style={styles.playButton}
                                        onPress={isFinished ? replay : togglePlayPause}
                                    >
                                        <MaterialIcons
                                            name={isFinished ? "replay" : (isPlaying ? "pause" : "play-arrow")}
                                            size={40}
                                            color="white"
                                        />
                                    </TouchableOpacity>
                                </View>

                                <View style={styles.bottomControls}>
                                    <Text style={styles.timeText}>{formatTime(position)}</Text>

                                    <Slider
                                        style={styles.slider}
                                        minimumValue={0}
                                        maximumValue={duration || 100}
                                        value={position}
                                        onValueChange={handleValueChange}
                                        onSlidingComplete={handleSlidingComplete}
                                        minimumTrackTintColor="#FFFFFF"
                                        maximumTrackTintColor="rgba(255, 255, 255, 0.5)"
                                        thumbTintColor="#FFFFFF"
                                    />

                                    <Text style={styles.timeText}>{formatTime(duration)}</Text>

                                    <TouchableOpacity
                                        style={styles.fullscreenButton}
                                        onPress={toggleFullscreen}
                                    >
                                        <MaterialIcons
                                            name={isFullscreen ? "fullscreen-exit" : "fullscreen"}
                                            size={24}
                                            color="white"
                                        />
                                    </TouchableOpacity>
                                </View>
                            </>
                        )}
                    </View>
                ) : null}
            </TouchableOpacity>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        borderRadius: 12,
        overflow: 'hidden',
        backgroundColor: '#000',
        aspectRatio: 16 / 9,
    },
    videoContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    video: {
        width: '100%',
        height: '100%',
    },
    overlay: {
        ...StyleSheet.absoluteFillObject,
        backgroundColor: 'rgba(0, 0, 0, 0.4)',
        justifyContent: 'space-between',
        padding: 10,
    },
    controlsContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    playButton: {
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
        borderRadius: 30,
        width: 60,
        height: 60,
        justifyContent: 'center',
        alignItems: 'center',
    },
    bottomControls: {
        flexDirection: 'row',
        alignItems: 'center',
        marginBottom: 10,
        paddingHorizontal: 10,
    },
    slider: {
        flex: 1,
        marginHorizontal: 10,
    },
    timeText: {
        color: 'white',
        fontSize: 12,
    },
    fullscreenButton: {
        marginLeft: 10,
    },
    errorContainer: {
        ...StyleSheet.absoluteFillObject,
        backgroundColor: 'rgba(0, 0, 0, 0.7)',
        justifyContent: 'center',
        alignItems: 'center',
        padding: 20,
    },
    errorText: {
        color: 'white',
        textAlign: 'center',
        marginTop: 10,
    },
});

export default VideoPlayer; 